﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PPIMobileInterface.Logic;
using PPIMobileInterface.Entities;
using PPIDesktopClient.Logic;
using PPIDesktopClient.Entities;
using PPIDesktopClient.General;
using VMind.Global;

namespace PPIDesktopClient.Controls.Uploader
{
    public partial class Uploader : UserControl
    {
        #region Private Properties
        private string m_mobiledatabasePath;
        private List<EVendor_Visit_XMissionStructure> m_VendorVisits;
        private int m_TotalData = 0;
        private bool m_UploadAllFolder = false;
        private bool m_Stopped = false;
        #endregion Private Properties

        #region Public Properties
        public string MobileDatabasePath
        {
            get { return m_mobiledatabasePath; }
            set { m_mobiledatabasePath = value; }
        }
        public bool UploadAllFolders
        {
            get { return m_UploadAllFolder; }
            set { m_UploadAllFolder = value; }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Gabriel Barzola
        /// 05/06/08
        /// 1. Initialize GUI.
        /// 2. Hide all Controls
        /// </summary>
        public Uploader()
        {
            InitializeComponent();
            HideShowControls(false);
        }
        #endregion


        #region Private Methods
        
        /// <summary>
        /// Gabriel Barzola
        /// 5/06/08
        /// Load all pending mobile pending visits in a List
        /// </summary>
        private void LoadVisits()
        {
            List<EVisit> _MobileVisits = LogicLayer.LoadAllCompleteVisits(m_mobiledatabasePath,false);
            m_VendorVisits = LVendor_Visit_XMissionStructure.GetListFromMobileVisits(_MobileVisits);
        }

        /// <summary>
        /// Gabriel Barzola
        /// 05/06/08
        /// 1. Check cancellation process
        /// 2. Show Controls.
        /// 3. Calculate total data to upload.
        /// 4. Upload asset and poles.
        /// 5. update StructureServerID in mobile database.
        /// 6. Report Progress
        /// </summary>
        /// <param name="e"></param>
        private void Upload(DoWorkEventArgs e)
        {
            HideShowControls(true);
            if (m_uploaderWorker.CancellationPending)
            {
                e.Cancel = true;
            }
            

            LoadVisits();
            CalculateTotalData();

            Int32 _CountUploaded = m_TotalData;
            Int32 _NewStructureServerID;
            Int32 _NewPoleServerID;

            foreach (EVendor_Visit_XMissionStructure Visit in m_VendorVisits)
            {
                if (m_uploaderWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                _NewStructureServerID = LVendor_Visit_XMissionStructure.UploadStructure(Visit);
                foreach (EVendor_Visit_XMissionStructures_Pole  Pole in Visit.Poles)
                {
                    if (m_uploaderWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }
                    _NewPoleServerID = LVendor_Visit_XMissionStructures_Pole.UploadPole(Pole, _NewStructureServerID);
                    LogicLayer.UpdatePoleServerID(_NewPoleServerID, Pole.Id,MobileDatabasePath);
                    _CountUploaded--;
                    m_uploaderWorker.ReportProgress(ReportProgress(_CountUploaded));
                    System.Threading.Thread.Sleep(ConvertHelper.ToInt32(ConfigurationManager.AppSettings["TimeWaitUpPoles"]));
                }
                LogicLayer.UpdateStructureServerID(_NewStructureServerID, Visit.Id, MobileDatabasePath);
                _CountUploaded--;
                m_uploaderWorker.ReportProgress(ReportProgress(_CountUploaded));
                System.Threading.Thread.Sleep(ConvertHelper.ToInt32(ConfigurationManager.AppSettings["TimeWaitUpStructures"]));

            }
        }
        
        /// <summary>
        /// Gabriel Barzola
        /// 05/06/08
        /// 1. Calculate progress percentage.
        /// </summary>
        /// <param name="_CountUploaded"></param>
        /// <returns></returns>
        private int ReportProgress(int _CountUploaded)
        {
            int _Progress;
            try
            {
                _Progress = ((m_TotalData - _CountUploaded) * 100) / m_TotalData;
            }
            catch (Exception)
            {
                _Progress = 0;
            }
            return _Progress;
        }
        
        /// <summary>
        /// Gabriel Barzola
        /// 05/06/08
        /// 1. Count poles and visits.
        /// </summary>
        private void CalculateTotalData()
        {
            foreach (EVendor_Visit_XMissionStructure Visit in m_VendorVisits)
            {
                m_TotalData += Visit.Poles.Count;
            }
            m_TotalData += m_VendorVisits.Count;
        }

        private delegate void HideShowControlsCallback(bool status);

        private void HideShowControls(bool status)
        {
            if (this.InvokeRequired)
            {
                HideShowControlsCallback d = new HideShowControlsCallback(HideShowControls);
                this.Invoke(d, new object[]{status});
            }
            else
            {
                foreach (Control c in this.Controls)
                {
                    c.Visible = status;
                }
            }
        }
        
        #endregion

        #region Public Methods
        
        /// <summary>
        /// Gabriel Barzola
        /// 05/06/08
        /// 
        /// </summary>
        public void Start()
        {
            XMLHelper.CreateXML(Constants.K_XmlOutboxPath);
            if (XMLHelper.HasNextFolder(Constants.K_XmlOutboxPath) && !m_uploaderWorker.IsBusy)
            {
                m_mobiledatabasePath = XMLHelper.GetNextFolder(Constants.K_XmlOutboxPath);
                m_uploaderWorker.RunWorkerAsync();
                m_Stopped = false;
                this.btnStop.Image = global::PPIDesktopClient.Properties.Resources.Stop;
            }
        }
        public void Stop()
        {
            m_uploaderWorker.CancelAsync();
            m_Stopped = !m_Stopped;
            this.btnStop.Image = global::PPIDesktopClient.Properties.Resources.Play;
                
        }
        #endregion

        #region Events
        private void m_uploaderWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                m_TotalData = 0;
                progressBarUploader.Value = 0;
                lblShowStats.Text = "";

                if (!e.Cancelled)
                {
                    if (!string.IsNullOrEmpty(m_mobiledatabasePath))
                    {
                        string[] _NameFolder = m_mobiledatabasePath.Split("\\".ToCharArray());
                        string _IDFolder = _NameFolder[_NameFolder.Length - 2];
                        XMLHelper.UpdateFolderNode(Constants.K_XmlOutboxPath, _IDFolder);
                    }
                    if (XMLHelper.HasNextFolder(Constants.K_XmlOutboxPath) && !m_uploaderWorker.IsBusy)
                    {
                        m_mobiledatabasePath = XMLHelper.GetNextFolder(Constants.K_XmlOutboxPath);
                        m_uploaderWorker.RunWorkerAsync();
                    }
                    else
                    {
                        HideShowControls(false);
                    }
                }
                else
                {
                    HideShowControls(false);
                }
            }
            catch (Exception ex)
            {
                ErrorManager.Log("Exception", "m_uploaderWorker_RunWorkerCompleted " + ex.TargetSite, ex.Message, ex.StackTrace);
            }
        }
        private void m_uploaderWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int countUploaded = (((((e.ProgressPercentage * m_TotalData) / 100) - m_TotalData) * -1) - m_TotalData) * -1;
            if (countUploaded != m_TotalData)
                countUploaded++;
            lblShowStats.Text = (countUploaded) + " / " + m_TotalData.ToString();  
            progressBarUploader.Value = e.ProgressPercentage;
        }
        private void m_uploaderWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                BackgroundWorker bw = (BackgroundWorker)sender;
                if (bw.CancellationPending)
                {
                    e.Cancel = true;
                }
                Upload(e);
            }
            catch (Exception ex)
            {
                ErrorManager.Log("Exception", "m_uploaderWorker_DoWork " + ex.TargetSite, ex.Message, ex.StackTrace);
            }
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            Start();
        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            if (m_Stopped)
                Start();
            else
                Stop();
        }
        #endregion



    }
}
